import TableHead from '@/components/quarterly-account-table-new/table-head.vue'
import ReportPerson from '@/components/quarterly-account-table-new/report-person.vue'
import { uuid } from '@/utils'
import { loadDescription } from '@/api/descriptionManagement'
import {
  TABLE_FIELD_QUARTER,
  TABLE_FIELD_YEAR,
  ENTERPRISE_BASIC_INFORMATION_TABLE_ID,
  TABLE_OF_COMPREHENSIVE_ENERGY_CONSUMPTION_PER_UNIT_PRODUCT,
  ENERGY_SAVING_RENOVATION_PROJECT_INFORMATION_TABLE,
  ENERGY_CONSUMPTION_STRUCTURE_TABLE,
  ENERGY_CONSUMPTION_STRUCTURE_SUB_TABLE
} from '@/config'

// 输入框只能输入正数
function positiveNumber(inputValue) {
  let result = inputValue;
  const regex = /^\d*(\.\d+)?$/; // 匹配正整数或小数
  if (!regex.test(inputValue) || (inputValue.startsWith('.'))) {
    if (inputValue.startsWith('.')) {
      result = result.substring(1);
      result = result.replace(/[^\d.]/g, '')
    } else {
      result = inputValue.match(/^\d*(\.\d+)?$/) ? inputValue : inputValue.replace(/[^\d.]/g, '');
    }
  }

  if (result.startsWith('0') && !result.startsWith('0.')) {
    result = result.split('.').map(v => Number(v)).join(',')
  }

  // 如果有多个小数点
  if (result.indexOf('.') !== result.lastIndexOf('.')) {
    const i = result.indexOf('.')
    if (i > -1) {
      result = result.replace(/[.]/g, '')
      result = result.substring(0, i) + '.' + result.substring(i);
    }
  }

  result = result.replace(/[^\d.]/g, '')
  return result;
}

export default {
  components: {
    TableHead,
    ReportPerson
  },
  props: {
    // 企业ID
    enterpriseId: {
      type: String,
      required: true,
    },
    // 企业名称
    enterpriseName: String,
    // 年份
    year: {
      type: [String, Number],
      required: true,
    },
    // 季度
    quarter: {
      type: [String, Number],
      required: true,
    },
    // 表ID
    tId: {
      type: Number,
      required: true,
    },
    // 表名称
    name: {
      type: String,
      required: true,
    },
    // 表数据项
    columns: {
      type: Array,
      required: true,
    },
    // 政府端
    isGovernment: Boolean,
    readonly: Boolean,
    showLineNumber: {
      type: Boolean,
      default: true,
    }
  },
  directives: {
    // 输入只能输入“是”或“否”
    onlyIsOrNo: {
      bind (el, binding) {
        if (binding.value === false) return
        el.setAttribute('placeholder', '请输入是或否')
        el.__is_or_no_handler__ = function isOrNoHandler (evt) {
          el.value = el.value.replace(/[^是|否]/g, '')
          if (binding.value && typeof binding.value === 'function') {
            binding.value(el.value)
         }
        }
        el.addEventListener('keyup', el.__is_or_no_handler__, false)
        el.addEventListener('blur', el.__is_or_no_handler__, false)
      },
      unbind (el) {
        if (el.__is_or_no_handler__) {
          el.removeEventListener('keyup', el.__is_or_no_handler__, false)
          el.removeEventListener('blur', el.__is_or_no_handler__, false)
          delete el.__is_or_no_handler__
        }
      }
    },
    // 输入框只能输入正数
    onlyPositiveNumber: {
      bind (el, binding) {
        if (binding.value === false) return
        el.__positive_number_handler__ = function positiveNumberHandler (evt) {
          el.value = positiveNumber(el.value)
          if (binding.value && typeof binding.value === 'function') {
            binding.value(el.value)
          }
        }
        el.__positive_number_handler_blur__ = function () {
          try {
            const v = positiveNumber(el.value)
            if (v.endsWith('.')) {
              el.value = v.substring(0, v.length - 1)
            }
            if (binding.value && typeof binding.value === 'function') {
              binding.value(el.value)
            }
          } catch (e) {}
        }
        el.addEventListener('input', el.__positive_number_handler__, false)
        el.addEventListener('blur', el.__positive_number_handler_blur__, false)
      },
      unbind (el) {
        if (el.__positive_number_handler__) {
          el.removeEventListener('blur', el.__positive_number_handler__, false)
          delete el.__positive_number_handler__
        }
        if (el.__positive_number_handler_blur__) {
          el.removeEventListener('input', el.__positive_number_handler_blur__, false)
          delete el.__positive_number_handler_blur__
        }
      }
    },
    // 整数
    onlyInteger: {
      bind (el, binding) {
        if (binding.value === false) return
        // el.setAttribute('placeholder', '请输入整数')
        el.__integer_handler__ = function integerHandler (evt) {
          el.value = el.value.replace(/[^\d]/g, '')
          if (binding.value && typeof binding.value === 'function') {
            binding.value(el.value)
          }
        }
        el.__integer_blur_handler__ = function integerHandler (evt) {
          const v = el.value.replace(/[^\d]/g, '')
          el.value = Number(v);
          if (binding.value && typeof binding.value === 'function') {
            binding.value(el.value)
          }
        }
        el.addEventListener('input', el.__integer_handler__, false)
        el.addEventListener('blur', el.__integer_blur_handler__, false)
      },
      unbind (el) {
        if (el.__integer_handler__) {
          el.removeEventListener('input', el.__integer_handler__, false)
          el.removeEventListener('blur', el.__integer_blur_handler__, false)
          delete el.__integer_handler__
          delete el.__integer_blur_handler__
        }
      }
    },
    // 纯数字
    onlyNumber: {
      bind (el, binding) {
        if (binding.value === false) return
        el.setAttribute('maxlength', 20)
        el.__number_handler__ = function numberHandler (evt) {
          el.value = el.value.replace(/[^\d]/g, '')
          if (binding.value && typeof binding.value === 'function') {
            binding.value(el.value)
          }
        }
        el.addEventListener('input', el.__number_handler__, false)
        el.addEventListener('blur', el.__number_handler__, false)
      },
      unbind (el) {
        if (el.__number_handler__) {
          el.removeEventListener('input', el.__number_handler__, false)
          el.removeEventListener('blur', el.__number_handler__, false)
          delete el.__number_handler__
        }
      }
    }
  },
  data () {
    return {
      // 点击单元格后，正在输入的input索引
      inputIndex: -1,
      rowIndex: -1,
      /**
       * 报表数据格式
       * @types {
       *    uuid: string,
       *    data: {
       *      value: string;
       *      calculable: boolean;
       *      readonly: boolean;
       *      background: boolean;
       *    }[]
       * }[]
       */
      lists: [],

      // context menu box
      left: 0,
      top: 0,

      // 填报说明
      tableDescription: '',

      // 防止自动保存发生在请求数据之前
      loading: true,

      // 加载上期数据时填报人信息对象不用更新
      isKept: false,
    }
  },
  computed: {
    title () {
      const s = this.enterpriseName || '';
      // 年度
      if (Number(this.quarter) === 5) {
        return `${this.year}年度-${s}-${this.name}`
      }

      return `${this.year}年第${this.quarter}季度-${s}-${this.name}`
    },
    fromGovernmentSide () {
      return this.isGovernment && this.readonly === true
    },
    // 多级表头转一级表头
    flattenColumns () {
      const columns = this.columns
      const getItems = (arr) => {
        const result = [];
        (function callback (arr) {
          for (let i = 0; i < arr.length; i++) {
            const { children, ...rest } = arr[i]
            if (children && children.length > 0) {
              callback(children)
            } else if (!rest.hidden) {
              result.push({ ...rest })
            }
          }
        })(arr)
        return result
      }
      return getItems(columns)
    },
    // 填报人相关信息
    informant () {
      if (this.selfInformant) {
        return this.selfInformant;
      }
      const lists = this.lists
      const item = lists[0] && lists[0].informant
      if (!item) {
        return {}
      }
      return {
        principal: item.personInCharge || '',
        informant: item.informer || '',
        telephone: item.telephone || '',
        date: item.fillInDate || '',
      }
    },
  },
  mounted () {
    this.getDescription(this.tId)
    const res = this.initLists()
    if (res && res.finally) {
      res.finally(() => {
        this.loading = false
      })
    } else {
      this.loading = false
    }
  },
  methods: {
    // 加载上期数据
    getPrevLists (params) {
      if (this.tId === ENTERPRISE_BASIC_INFORMATION_TABLE_ID ||
        this.tId === TABLE_OF_COMPREHENSIVE_ENERGY_CONSUMPTION_PER_UNIT_PRODUCT.ID ||
        this.tId === ENERGY_CONSUMPTION_STRUCTURE_TABLE.ID ||
        this.tId === ENERGY_CONSUMPTION_STRUCTURE_SUB_TABLE.ID
      ) {
        // 企业基本情况表点击要特殊处理
        // 第二个参数 loadOnClickPrevButton ，“本期”填充“上期”数据
        // 第三个参数 needInformant ，加载上期数据时不需要覆盖填报人信息
        return this.initLists(params, true, false);
      }
      // 第二个参数 needInformant ，加载上期数据时不需要覆盖填报人信息
      return this.initLists(params, false)
    },
    refresh () {
      this.initLists()
    },
    _initLists (l, min) {
      min = min || 2
      if (l < min) {
        let rest = []
        if (this.transfer) {
          rest = this.transfer(Array(min - l).fill({}))
        } else {
          const columns = this.flattenColumns
          rest = Array(min - l).fill(1).map(() => ({
            uuid: uuid(),
            data: columns.map(v => ({
              key: v.prop,
              value: '',
              editable: !this.readonly
            }))
          }))
        }
        this.lists = this.lists.concat(rest)
      }
    },
    // 暴露给使用者的获取填报人相关信息
    getInformer () {
      return this.$refs.reportPerson && this.$refs.reportPerson.getData()
    },
    // 暴露给使用者的获取报表数据的方法
    // @return [{prop1: string, prop2: string, ...}]
    getData () {
      let props = this.flattenColumns.map(v => v.prop)

      if (+this.tId === ENERGY_SAVING_RENOVATION_PROJECT_INFORMATION_TABLE.ID) {
        props = props.filter(key => key !== 'serialNumber')
      }

      const isNotEmpty = (array) => array.some(
        v => v.value !== ''
      )

      // 二维数组 [string[], string[], ...]
      const lists = this.lists.filter(v => isNotEmpty(v.data))
      return lists.map((v, i) => {
        v = v.data || []
        const obj = {}
        props.forEach((prop) => {
          const target = v.find(vv => vv.key === prop)
          if (target) {
            obj[prop] = typeof this.getCalc === 'function'
              ? String(this.getCalc(i, prop, target.value) || '')
              : (!this.is_empty_value(target.value) ? target.value : '')
          }
        })
        obj[TABLE_FIELD_YEAR] = String(this.year)
        obj[TABLE_FIELD_QUARTER] = String(this.quarter)
        return obj
      })
    },
    // 单击单元格（input框）
    clickHandler (evt, rowIndex) {
      // evt.target.select()
      this.inputIndex = Number(evt.target.dataset.inputIndex)
      this.rowIndex = rowIndex


      // 表1-2，1-2-1 点击原煤子项输入框任意一个，提示“是否使用原煤子项合计值替代原煤数值”
      if (this.maybe_i_want_to_use_yuanmei && this.isQiZhong &&
        this.isQiZhong(this.lists[rowIndex] ? this.lists[rowIndex].data : []) &&
        !this.useQizhong
      ) {
        this.$confirm('是否使用原煤子项合计值替代原煤数值？', '提示')
          .then(() => {
            evt.target.focus()
          })
          .catch(() => {
            evt.target.blur()
          })
      }
      this.visible = false
    },
    // 给每个input添加索引
    initInputIndex () {
      const inputs = document.querySelectorAll('.input-cell input')
      inputs.forEach((input, index) => {
        input.dataset.inputIndex = index + ''
      })
    },
    // 获取填报说明
    async getDescription (tId) {
      const { data } = await loadDescription(tId)
      const { descriptionContent } = data || {}
      this.tableDescription = descriptionContent
    },
    validateInformant () {
      return this.$refs.reportPerson.validate()
    },
    // 处理null undefined ''
    is_empty_value (val) {
      // eslint-disable-next-line
      return val == null || val === ''
    }
  }
}
